package com.iqiyi.pps.epg.core.rpc.qipu.Composite;

import com.alibaba.fastjson.JSONObject;
import com.iqiyi.pps.epg.core.model.channel.ChannelBase;
import com.iqiyi.pps.epg.core.model.channel.ChannelBoss;
import com.iqiyi.pps.epg.core.model.channel.ChannelTag;
import com.iqiyi.pps.epg.core.model.stream.LiveChannelStream;
import com.iqiyi.pps.epg.core.model.stream.LiveStream;
import com.iqiyi.pps.epg.core.rpc.qipu.impl.QipuManager;
import com.iqiyi.pps.epg.core.service.channel.ChannelService;
import com.iqiyi.pps.epg.core.service.stream.LiveChannelStreamService;
import com.iqiyi.pps.epg.core.service.stream.LiveStreamService;
import knowledge.pub.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by karkarrotxu on 2015/11/10.
 */
@Service
public class NodeLiveChannelImpl {
    private static final Logger logger = LoggerFactory.getLogger(NodeLiveChannelImpl.class);
    @Autowired
    private NodeCommonImpl commonImpl;
    @Autowired
    private ChannelService channelService;
    @Autowired
    private AlternatePlayCollectionImpl alternatePlayCollectionImpl;
    @Autowired
    private LiveStreamService liveStreamService;
    @Autowired
    private LiveChannelStreamService liveChannelStreamService;
    @Autowired
    private QipuManager qipuManager;

    public int syncChannelDataListToNewQipu(ChannelBase channelBase) {
        return writeLiveChannelToQipu(channelBase);
    }

    // ===
    public int writeLiveChannelToQipu(ChannelBase channelBase) {
        Knowledge.LiveChannel.Builder channelBuilder = Knowledge.LiveChannel.newBuilder();
        channelBuilder.setId(channelBase.getQipuId());
        channelBuilder.setLiveChannelBase(getLiveBase(channelBase));
        if (null != channelBase.getSubjectUrl()) {
            channelBuilder.setSubjectUrl(channelBase.getSubjectUrl());
        }
        if (StringUtils.isNotEmpty(channelBase.getDefaultLogoUrl())) {
            fillChannelLogo(channelBase, channelBuilder);
        }
        channelBuilder.setIsEnable(channelBase.getIsEnable() != null && channelBase.getIsEnable() > 0);
        channelBuilder.setQitan(commonImpl.getQitan(channelBase.getQitanId(), channelBase.getShouldDisplay() > 0));
        Knowledge.LiveChannel.Builder deleteBuilder =  clearQipuOldData( channelBase  );
        fillDefaultStream(channelBase, channelBuilder);
        fillLiveStream(channelBase, channelBuilder);

        List<String> tags = fillTag(channelBase);
        for (String tag : tags) {
            channelBuilder.addTag(tag);
        }

        fillLiveChannelBoss(channelBase, channelBuilder);
        fillChannelPageUrl(channelBase, channelBuilder);
        fillChannelPanoFormat(channelBase, channelBuilder);
        fillChannelThreeD(channelBase, channelBuilder);
        if( deleteBuilder!= null ){
          return   commonImpl.setEntity(channelBuilder.build(),deleteBuilder.build() );
        }else{
            return commonImpl.writeEntity(channelBuilder.build());
        }
    }

    public Knowledge.LiveChannel.Builder clearQipuOldData( ChannelBase channelBase ){
        Knowledge.LiveChannel oldData = commonImpl.getLiveChannel(channelBase.getQipuId());
        if(oldData == null ){
            return null;
        }
        Knowledge.LiveChannel.Builder deleteBuilder = commonImpl.newLiveChannelBuilder(channelBase.getQipuId());
        // * 删除奇谱频道大小写分类 （删除老奇谱大小写分类也可用此方法，此时entityId传老奇谱ID）
        if (oldData != null && oldData.getTagCount() >  0) {
            deleteBuilder.addAllTag(oldData.getTagList());
        }else{
            logger.info("[delAllTags][entityId={}][isNull={}] skip case no tag", channelBase.getQipuId(),oldData == null);
        }

        //删除码流
        if (oldData != null && oldData.getLiveStreamCount()>  0) {
            deleteBuilder.addAllLiveStream( oldData.getLiveStreamList() );
        }else{
            logger.info("[delAllStream][entityId={}][isNull={}] skip case no stream", channelBase.getQipuId(),oldData == null);
        }
        return deleteBuilder;
    }

    public void fillChannelLogo(ChannelBase channelBase, Knowledge.LiveChannel.Builder channelBuilder) {
        Common.KeyValuePair.Builder keyValuePairBuilder = Common.KeyValuePair.newBuilder();
        keyValuePairBuilder.setName("imageformat_livechannel_logo");
        keyValuePairBuilder.setValue(channelBase.getDefaultLogoUrl());
        channelBuilder.addKeyValuePair(keyValuePairBuilder);
    }

    public void fillDefaultStream(ChannelBase channelBase, Knowledge.LiveChannel.Builder channelBuilder) {
        LiveStream defaultStream = qipuManager.getDefaultLiveStreamByChannel(channelBase.getQipuId());
        if (isWriteLiveStream(defaultStream) && null != defaultStream) {
            LiveChannelStream defaultLiveChannelStream = liveChannelStreamService.get(defaultStream.getFatherId(), defaultStream.getStreamName());
            if (defaultLiveChannelStream != null && defaultLiveChannelStream.getIsEnable()) {
                channelBuilder.setDefaultLiveStream(getLiveStreamData(defaultStream, defaultLiveChannelStream));
            }
        }
    }

    public Properties.LiveStream.Builder getLiveStreamData(LiveStream liveStreamData, LiveChannelStream liveChannelStreamData) {
        Properties.LiveStream.Builder liveStream = Properties.LiveStream.newBuilder();
        if (liveStreamData != null) {
            if (liveChannelStreamData == null) {
                liveChannelStreamData = liveChannelStreamService.get(liveStreamData.getFatherId(), liveStreamData.getStreamName());
            }

            if(liveStreamData.getFormatType().equals(LiveStream.FORMATTYPE_HCDN) ||
                    liveStreamData.getFormatType().equals(LiveStream.FORMATTYPE_HLFLV)) {
                LiveStream flvStream = liveStreamService.get(liveStreamData.getFatherId(), liveStreamData.getStreamName(),
                        LiveStream.FORMATTYPE_FLV);

                if (null == flvStream) {
                    logger.info("[NodeLiveChannelImpl][getLiveStreamData][LiveStreamData={}][no flv stream]", JSONObject.toJSON(liveStreamData));
                    liveStream.setStreamName("");
                } else {
                    liveStream.setStreamName(flvStream.getUrl());
                }

            }else if(liveStreamData.getFormatType().equals(LiveStream.FORMATTYPE_DOLBY)) {
                liveStream.setStreamName(liveStreamData.getDolby_ch());
            }else if(liveStreamData.getFormatType().equals(LiveStream.FORMATTYPE_TS) && StringUtils.isNotEmpty(liveStreamData.getDolby_ch())) {
                liveStream.setStreamName(liveStreamData.getDolby_ch());
            }else{
                liveStream.setStreamName(liveStreamData.getUrl());
            }

            liveStream.setUuid(liveStreamData.getUuid()); // 流对应的UUID
            liveStream.setStreamType(liveChannelStreamData.toQipuStreamType()); // 清晰度
            liveStream.setBitRate(liveChannelStreamData.getBitRate() + ""); // 码流
            liveStream.setUrl(liveStreamData.toQipuUrl()); // 播放id/url
            liveStream.setAspectRatio(liveChannelStreamData.getAspectRatio()); // 画面比例
            liveStream.setScreenSize(liveChannelStreamData.getScreenSize()); // 画面尺寸

            if(liveStreamData.getFormatType().equals(LiveStream.FORMATTYPE_DOLBY)) {
                liveStream.setFormatType(liveStreamData.getFormatType() + "_" + liveChannelStreamData.getDolbyAudioChannel());
            }else{
                liveStream.setFormatType(liveStreamData.getFormatType()); // 码流文件格式
            }

            if(liveChannelStreamData.getEncodeType() == LiveChannelStream.ENCODE_H264) {
                liveStream.setCode(Formats.Format.Code.H264);
            }else if(liveChannelStreamData.getEncodeType() == LiveChannelStream.ENCODE_H265) {
                liveStream.setCode(Formats.Format.Code.H265);
            }
        }
        return liveStream;
    }

    public boolean isWriteLiveStream(LiveStream liveStream) {
        return null != liveStream && (liveStream.getStatus() == LiveStream.STATUS_START || liveStream.getStatus() == LiveStream.STATUS_STOP);
    }

    public void fillLiveStream(ChannelBase channelBase, Knowledge.LiveChannel.Builder channelBuilder) {
        List<LiveStream> liveStreamList = liveStreamService.get(channelBase.getId(), null);
        if (liveStreamList != null && liveStreamList.size() > 0) {
            addLiveStream(liveStreamList, channelBuilder);
        }
    }


    public void addLiveStream(List<LiveStream> liveStreamList, Knowledge.LiveChannel.Builder channelBuilder) {
        for (LiveStream liveStream : liveStreamList) {
            LiveChannelStream liveChannelStream = liveChannelStreamService.get(liveStream.getFatherId(), liveStream.getStreamName());
            if (liveChannelStream != null && liveChannelStream.getIsEnable() && isWriteLiveStream(liveStream)) {
                channelBuilder.addLiveStream(getLiveStreamData(liveStream, liveChannelStream));
            }
        }
    }

    public List<String> fillTag(ChannelBase channelBase) {
        if(channelBase.getLiveType() == ChannelBase.LIVE_TYPE_LS){
            return new ArrayList<String>();
        }
        List<ChannelTag> channelTagList = channelService.getChannelTag(channelBase.getId());
        List<String> list = new ArrayList<String>();
        if (channelTagList != null && channelTagList.size() > 0) {
            for (ChannelTag channelTag : channelTagList) {
                list.add("Tag_Pps_Category_" + (channelTag.getTag2() > 0 ? channelTag.getTag2() : channelTag.getTag1()));
            }
        }
        return list;
    }

    public void fillLiveChannelBoss(ChannelBase channelBase, Knowledge.LiveChannel.Builder channelBuilder) {
        ChannelBoss channelBoss = channelService.getChannelBoss(channelBase.getId());
        if (channelBoss != null && channelBoss.getId() > 0) {
            Properties.Boss.Builder boss = Properties.Boss.newBuilder();
            logger.info("[QipuManager][setLiveChannelBossToQipu][info][IsMemberOnly={}][IsMemeberFree={}][status={}][start_time={}][end_time={}]",
                    channelBoss.getIsMemberOnly(), channelBoss.getIsMemeberFree(), channelBoss.getStatus(), channelBoss.getPaidStartTime(), channelBoss.getPaidEndTime());
            // 设置付费信息
            boss.setIsMemberOnly(channelBoss.getIsMemberOnly() > 0 ? true : false); // 是否会员视频(0:不是,1;是)
            boss.setIsMemeberFree(channelBoss.getIsMemeberFree() > 0 ? true : false); // 是否付费(0:付费,1:免费)
            boss.setStatus(Properties.Boss.Status.valueOf(channelBoss.getStatus())); // 划价状态(PAIED_AVAILABLE:付费已划价 PAIED_NOT_AVAILABLE :付费未划价 FREE :免费)
            boss.setPaidStartTime(channelBoss.getPaidStartTime().getTime()); // 付费开始时间
            boss.setPaidEndTime(channelBoss.getPaidEndTime().getTime()); // 付费结束时间
            channelBuilder.setBoss(boss);
        }
    }

    public void fillChannelPageUrl(ChannelBase channelBase, Knowledge.LiveChannel.Builder channelBuilder) {
        channelBuilder.setPageUrl(channelBase.getPageUrl());
    }

    public void fillChannelPanoFormat(ChannelBase channelBase, Knowledge.LiveChannel.Builder channelBuilder) {
        String panoFormat = channelBase.getPanoFormat();
        if (panoFormat != null) {
            Formats.PanoFormat.Builder panoBuilder = Formats.PanoFormat.newBuilder();
            if (panoFormat != null) {
                JSONObject panoObject = JSONObject.parseObject(panoFormat);
                if (panoObject.containsKey("videoType")) {
                    panoBuilder.setVideoType(Formats.PanoFormat.VideoType.valueOf(panoObject.getIntValue("videoType")));
                } else {
                    logger.info("[QipuManager][setChannelPanoFormatToQipu] not contains videoType ");
                    return;
                }
                panoBuilder.setViewAngleX(panoObject.getIntValue("angleX"));
                panoBuilder.setViewAngleY(panoObject.getIntValue("angleY"));
                if (panoObject.containsKey("zoomRate")) {
                    panoBuilder.setZoomRate(panoObject.getFloatValue("zoomRate"));
                } else {
                    panoBuilder.setZoomRate(1.0f);
                }
            }
            channelBuilder.setPanoFormat(panoBuilder);
        }
    }

    public void fillChannelThreeD(ChannelBase channelBase, Knowledge.LiveChannel.Builder channelBuilder) {
        String threeD = channelBase.getThreeD();
        if(threeD != null) {
            Formats.ThreeDFormat.Builder threeDBuilder = Formats.ThreeDFormat.newBuilder();
            if(threeD != null) {
                JSONObject threeDObject = JSONObject.parseObject(threeD);
                if(threeDObject != null && threeDObject.containsKey("videoType")){
                    threeDBuilder.setThreeDType(Common.ThreeDType.valueOf(threeDObject.getIntValue("videoType")));
                }else{
                    logger.info("[QipuManager][fillChannelThreeD] not contains videoType ");
                    return;
                }
            }
            channelBuilder.setThreeDFormat(threeDBuilder);
        }

    }

    public Properties.LiveChannelBase.Builder getLiveBase(ChannelBase channelBase) {
        Properties.LiveChannelBase.Builder liveBase = Properties.LiveChannelBase.newBuilder();

        // 设置直播频道基本信息
        liveBase.setName(channelBase.getName()); // 频道名称
        liveBase.setShortName(channelBase.getShortName()); // 频道简称
        liveBase.setAbbrName(""); // 一个直播频道可能对应多个流名称，这里写不填写
        liveBase.setUniversalCode(channelBase.getUniversalCode()); // 直播频道代码（拉取节目单唯一标识）
        liveBase.setDescription(channelBase.getDescription()); // 频道描述
        liveBase.addPassportId(channelBase.getPassportId()); // 频道大V账号
        liveBase.setPpsBaikeId(channelBase.getPpsBaikeId()); // 频道PPS 百科ID
        liveBase.setLiveType(Common.LiveType.valueOf(channelBase.getLiveType())); // 直播类型
        liveBase.setType(Common.LiveChannelType.valueOf(channelBase.getType())); // 频道分类
        liveBase.setMaxPlaybackPeriod(channelBase.getMaxPlaybackPeriod()); // 支持最大回看时间
        if (channelBase.getLiveType() == ChannelBase.LIVE_TYPE_LB) {
            liveBase.setOrder(channelBase.getCarouselTableNo()); // 频道排序
        } else {
            liveBase.setOrder(0);
        }
        liveBase.setAllowPopups(channelBase.getAllowPopups() > 0 ? true : false);
        liveBase.setIsQiyiProduced(channelBase.getIsQiyiProduced() > 0 ? true : false); // 是否奇艺出品
        liveBase.setExclusiveStatusIqiyi(channelBase.getExclusiveStatusIqiyi() > 0 ? true : false); // 是否奇艺独播

        liveBase.setCarouselTableNo(channelBase.getCarouselTableNo()); // 轮播台台号

        List<Metadatas.MetaSummary> metaList = alternatePlayCollectionImpl.convertToMeta(channelBase.getAlternatePlayCollection());
        logger.info("[NodeLiveChannelImpl][getLiveBase][channelId={}][alternatePlayCollectionImpl][metaList={}]", channelBase.getId(), metaList.toString());
        if (!metaList.isEmpty()) {
            liveBase.addAllAlternatePlayCollectionSummary(metaList);       //备播库
        }else {
            liveBase.addAllAlternatePlayCollectionSummary(new ArrayList<Metadatas.MetaSummary>());
        }
        if (channelBase.getEpisodeUpdateTime() != null) {
            liveBase.setEpisodeUpdateTime(channelBase.getEpisodeUpdateTime().getTime()); // 节目单最新更新时间
        }

        liveBase.setPlayerTips(channelService.getConfigData("InterruptType", channelBase.getInterruptHintType()).getDescr());
        // 设置频道别名
        if (StringUtils.isNotEmpty(channelBase.getTempName())) {
            Properties.LiveChannelBase.TempName.Builder tmpName = Properties.LiveChannelBase.TempName.newBuilder();

            tmpName.setAlias(channelBase.getTempName());
            tmpName.setStartTime(channelBase.getTempStartTime().getTime());
            tmpName.setEndTime(channelBase.getTempEndTime().getTime());
            liveBase.setTempName(tmpName);
        }

        // 设置频道地区信息
        Common.Location.Builder locatoin = Common.Location.newBuilder();
        locatoin.setCountry(channelBase.getLocation());
        //locatoin.setCountryId(48); // TODO 此次要根据上面地区名找到地区ID
        liveBase.setLocation(locatoin);

        Metadatas.MetaSummary.Builder metaSu = Metadatas.MetaSummary.newBuilder();
        metaSu.setEntityId(channelBase.getLogoEntityId());
        metaSu.setType(Metadatas.MetaSummary.Type.IMAGE_COVER);
        liveBase.setLogo(metaSu);

        return liveBase;
    }

    public Properties.TvLiveStreamList.Builder getTvLiveStreamList(Long fatherId, List<LiveStream> liveStreamDatas) {
        Properties.TvLiveStreamList.Builder tvLiveStreamList = Properties.TvLiveStreamList.newBuilder();
        tvLiveStreamList.setTvChannelId(fatherId.intValue()); // 频道ID master_channel -> Id
        tvLiveStreamList.setIsAvailableStatus(true); // 此多路流状态

        // 写多路流信息[BEGIN]
        Properties.TvLiveStreamList.TvLiveStreamInfo.Builder tvLiveStreamInfo = Properties.TvLiveStreamList.TvLiveStreamInfo.newBuilder();
        tvLiveStreamInfo.addAllowedPlatform(Common.DistributionPlatform.PC_IQIYI); // allowed_platform 此处写死
        tvLiveStreamInfo.addAllowedPlatform(Common.DistributionPlatform.PC_PPS);
        for (LiveStream liveStreamData : liveStreamDatas) {
            if (liveStreamData.getStatus().intValue() == 2) {
                continue;
            }

            LiveChannelStream liveChannelStreamData = liveChannelStreamService.get(liveStreamData.getFatherId(), liveStreamData.getStreamName());
            tvLiveStreamInfo.setName(liveStreamData.getStreamName()); // 流名称
            tvLiveStreamInfo.setBrand(Common.Brand.IQIYI_PPS); // 品牌
            tvLiveStreamInfo.setStreamType(liveChannelStreamData.toTvQipuStreamType()); // 此流清晰度
            tvLiveStreamInfo.setBitrate(liveChannelStreamData.getBitRate() + ""); // 码率
            tvLiveStreamInfo.setUrl(liveStreamData.toTvQipuUrl()); // 播放URL
            tvLiveStreamInfo.setAspectRatio(liveChannelStreamData.getAspectRatio()); // aspect_ratio
            tvLiveStreamInfo.setScreenSize(liveChannelStreamData.getScreenSize()); // screen_size
            tvLiveStreamInfo.setFormatType(liveStreamData.toTvQipuFormatType()); // 流类型

            tvLiveStreamList.addTvLiveStreamInfo(tvLiveStreamInfo);
        }
        // 写多路流信息[END]
        return tvLiveStreamList;
    }

    public Properties.TvChannel.Builder getTvChannel(ChannelBase channelBase) {
        Properties.TvChannel.Builder tvChannel = Properties.TvChannel.newBuilder();
        tvChannel.setId(channelBase.getId().intValue()); // 频道ID
        tvChannel.setName(channelBase.getName());
        tvChannel.setShortName(channelBase.getShortName());
        tvChannel.setUniversalCode(channelBase.getUniversalCode()); // 频道代码
        int type = channelBase.getType();
        if (channelBase.getType() == 5 || channelBase.getType() == 7 || channelBase.getType() == 8) {
            type = 9;
        }
        if (channelBase.getType() == 6) {
            type = 8;
        }
        if (channelBase.getType() == 10) {
            type = 6;
        }
        tvChannel.setType(Properties.TvChannel.Type.valueOf(type)); // 频道类型
        tvChannel.setPlayerScale("1"); // channel -> proportion
        tvChannel.setCountryCode(""); // 国家代码
        tvChannel.setCityCode(""); // 城市代码

        // 设置tv_channel 下 location 信息
        Common.Location.Builder location = Common.Location.newBuilder();
        location.setContinent("");
        location.setCountry("");
        location.setRegion("");
        location.setCity("");
        tvChannel.setLocation(location);
        String logoUrl = channelBase.getDefaultLogoUrl();
        if (StringUtils.isNotEmpty(logoUrl)) {
            tvChannel.setLogoImageUrl(logoUrl); // 频道LOGO图片地址
        }

        tvChannel.setIsEnable(channelBase.getIsEnable() > 0 ? true : false);
        tvChannel.setDescription(channelBase.getDescription()); // 频道描述
        tvChannel.setCutterChannelId(""); // master_channel -> iqiyi_mark
        tvChannel.setBaiduBaikeId(channelBase.getPpsBaikeId()); // 频道百科ID
        tvChannel.setLiveType(Common.LiveType.valueOf(channelBase.getLiveType())); // 频道类型
        tvChannel.setIsRecordArchive(true); // channel -> record
        tvChannel.setLookBackMaxDuration(channelBase.getMaxPlaybackPeriod()); // 最大回看时间
        tvChannel.setIsSatelliteChannel(true); // channel -> is_satellite
        return tvChannel;
    }

}
